package com.vip.fdfs.service.impl;

import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.vip.common.constant.SysConsts;
import com.vip.common.response.ErrorCode;
import com.vip.common.response.Result;
import com.vip.common.response.Results;
import com.vip.common.util.EmptyUtils;
import com.vip.fdfs.constant.FdfsConsts;
import com.vip.fdfs.dto.AddFileDTO;
import com.vip.fdfs.dto.ImageReturnDTO;
import com.vip.fdfs.entity.SysFastdfsFile;
import com.vip.fdfs.mapper.SysFastdfsFileMapper;
import com.vip.fdfs.service.IFastdfsFileService;
import com.vip.fdfs.util.FetchFrameUtils;
import com.vip.fdfs.util.FileDFSUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件数据Service实现
 *
 * @author wgb
 * @date 2019/12/24 21:23
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class FastdfsFileServiceImpl implements IFastdfsFileService {
    @Autowired
    private FileDFSUtils fileDFSUtils;
    @Autowired
    private SysFastdfsFileMapper fastdfsFileMapper;
    @Value("${thumb.image.prefix}")
    private String thumbImagePrefix;
    @Autowired
    private FastFileStorageClient storageClient;

    @Override
    public Result<String> uploadImageFile(AddFileDTO dto) {
        try {
            SysFastdfsFile fastdfsFile = new SysFastdfsFile();
            String fileName = dto.getFileName(), suffix = null;
            if (fileName.contains(".")) {
                suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
                fileName = fileName.substring(0, fileName.lastIndexOf("."));
            }
            BeanUtils.copyProperties(dto, fastdfsFile);
            fastdfsFile.setSuffix(suffix).setFileName(fileName);
            if (fastdfsFileMapper.insert(fastdfsFile) > 0) {
                return Results.newSuccessResult(thumbImagePrefix + fastdfsFile.getId(), "上传成功");
            }
        } catch (Exception e) {
            log.error("上传图片出错", e);
        }
        fileDFSUtils.deleteFile(dto.getPath());
        fileDFSUtils.deleteFile(dto.getThumbImagePath());
        return Results.newFailResult(ErrorCode.DB_ERROR, "上传失败");
    }

    @Override
    public Result<String> uploadFile(AddFileDTO dto) {
        try {
            SysFastdfsFile fastdfsFile = new SysFastdfsFile();
            String fileName = dto.getFileName(), suffix = null;
            if (fileName.contains(".")) {
                suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
                fileName = fileName.substring(0, fileName.lastIndexOf("."));
            }
            BeanUtils.copyProperties(dto, fastdfsFile);
            fastdfsFile.setSuffix(suffix).setFileName(fileName);
            if (fastdfsFileMapper.insert(fastdfsFile) > 0) {
                return Results.newSuccessResult(fastdfsFile.getId(), "上传成功");
            }
        } catch (Exception e) {
            log.error("上传文件出错", e);
        }
        fileDFSUtils.deleteFile(dto.getPath());
        return Results.newFailResult(ErrorCode.DB_ERROR, "上传失败");
    }

    @Override
    public Result<String> getImageThumbPath(String fileId) {
        try {
            SysFastdfsFile file = fastdfsFileMapper.selectById(fileId);
            if (!EmptyUtils.fieldsIsEmpty(file)) {
                if (SysConsts.IMAGE_TYPE.contains(file.getSuffix().toLowerCase())) {
                    return Results.newSuccessResult(file.getThumbImagePath());
                } else {
                    return Results.newFailResult(ErrorCode.FILE_ERROR, "非图片/PDF类型请先下载");
                }
            } else {
                return Results.newFailResult(ErrorCode.DB_ERROR, "该文件不存在");
            }
        } catch (Exception e) {
            log.error("查询文件路径出错");
        }
        return Results.newFailResult(ErrorCode.DB_ERROR, "查询文件出错");
    }

    @Override
    public Result<SysFastdfsFile> getFileInfoById(String fileId) {
        try {
            SysFastdfsFile file = fastdfsFileMapper.selectById(fileId);
            if (!EmptyUtils.fieldsIsEmpty(file)) {
                return Results.newSuccessResult(file);
            } else {
                return Results.newFailResult(ErrorCode.DB_ERROR, "该文件不存在");
            }
        } catch (Exception e) {
            log.error("查询文件路径出错");
        }
        return Results.newFailResult(ErrorCode.DB_ERROR, "查询文件出错");
    }

    @Override
    public Result<String> deleteFileById(String fileId) {
        try {
            SysFastdfsFile fileInfo = fastdfsFileMapper.selectById(fileId);
            if (!EmptyUtils.fieldsIsEmpty(fileInfo)) {
                Result<String> serverDelResult = fileDFSUtils.deleteFile(fileInfo.getPath());
                // 如果存在缩略图，则删除缩略图
                if(!EmptyUtils.basicIsEmpty(fileInfo.getThumbImagePath())){
                    fileDFSUtils.deleteFile(fileInfo.getThumbImagePath());
                }
                if (serverDelResult.isSuccess()) {
                    if (fastdfsFileMapper.deleteById(fileId) == 1) {
                        return Results.newSuccessResult(null, "删除成功");
                    }
                } else {
                    return Results.newFailResult(ErrorCode.DB_ERROR, "删除失败：文件不存在");
                }
            }
        } catch (Exception e) {
            log.error("删除文件出错");
        }
        return Results.newFailResult(ErrorCode.DB_ERROR, "删除失败");
    }

    @Override
    public Result<ImageReturnDTO> uploadImage(String bindingId, String description, String fileType, MultipartFile file) {
        try {
            Result<Map<String, String>> uploadResult = fileDFSUtils.upload(file);
            if (uploadResult.isSuccess()) {
                AddFileDTO dto = new AddFileDTO();
                dto.setFileName(file.getOriginalFilename()).setPath(uploadResult.getData().get("full_image_path")).setThumbImagePath(uploadResult.getData().get("thumb_image_path"))
                      .setBindingId(bindingId).setDescription(description).setFileType(fileType);
                Result<String> dataSaveResult = uploadImageFile(dto);
                ImageReturnDTO imageReturn = new ImageReturnDTO();
                imageReturn.setCode(dataSaveResult.getErrorCode().getCode());
                imageReturn.setMsg(dataSaveResult.getDescription());
                Map<String, String> imageInfo = new HashMap<>();
                imageInfo.put("src", dataSaveResult.getData());
                imageReturn.setData(imageInfo);
                return Results.newSuccessResult(imageReturn, "上传成功");
            }
        } catch (Exception e) {
            log.error("上传图片出错", e);
        }
        return Results.newFailResult(ErrorCode.FILE_UPLOAD, "上传失败");
    }

    @Override
    public String uploadFetchFrame(MultipartFile file) {
        try {
            String fileName = file.getOriginalFilename();
            String suffix = fileName.contains(".") ? fileName.substring(fileName.lastIndexOf(".") + 1) : null;
            if (!EmptyUtils.basicIsEmpty(suffix) && FdfsConsts.VIDEO_TYPE.contains(suffix.toLowerCase())) {
                InputStream fileInputStream = file.getInputStream();
                InputStream inputStream = FetchFrameUtils.getVideoPic(fileInputStream);
                StorePath storePath = this.storageClient.uploadFile(inputStream, inputStream.available(), "png", null);
                // 全路径(带组)
                return storePath.getFullPath();
            }
        } catch (Exception e) {
            log.error("上传视频截图出错");
        }
        return null;
    }
}
